package com.sky.chapter3.bq;


import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;

/**
 * 添加元素
 * add() 	如果插入成功则返回 true，否则抛出 IllegalStateException 异常
 * put() 	将指定的元素插入队列，如果队列满了，那么会阻塞直到有空间插入
 * offer() 	如果插入成功则返回 true，否则返回 false
 * offer(E e, long timeout, TimeUnit unit) 	尝试将元素插入队列，如果队列已满，那么会阻塞直到有空间插入
 *
 *
 * 检索元素
 * BlockingQueue 提供了以下方法用于检索元素
 * 方法 	说明
 * take():取出排在首位的对象，如果队列中没有数据，则会阻塞该线程直到有数据。
 * poll(long timeout, TimeUnit unit) 检索并删除队列的头部，如有必要，等待指定的等待时间以使元素可用，如果超时，则返回 null
 *
 * 查询
 * contains(obj):查询是否存在某个元素，返回true/false
 * peek():返回队列头部的元素，无则返回null
 * 在构建生产者 - 消费者程序时，这些方法是 BlockingQueue 接口中最重要的构建块。
 */
public class BqDemo1 {


    public static void main(String[] args) throws InterruptedException {
        test1();
    }

    private static void test1() throws InterruptedException {
        // 队列的大小
        ArrayBlockingQueue<String> blockingQueue = new ArrayBlockingQueue< >(3);

        System.out.println(blockingQueue.add("a"));
        System.out.println(blockingQueue.offer("b"));
        System.out.println(blockingQueue.add("c"));
        System.out.println();
        blockingQueue.put("d");
        // IllegalStateException: Queue full 抛出异常！
        // System.out.println(blockingQueue.add("d"));

        System.out.println("=============");

        System.out.println(blockingQueue.element()); // 查看队首元素是谁
        System.out.println(blockingQueue.remove());


        System.out.println(blockingQueue.remove());
        System.out.println(blockingQueue.remove());

        // java.util.NoSuchElementException 抛出异常！
        // System.out.println(blockingQueue.remove());
    }

    /**
     * 有返回值，没有异常
     */
    private static void test2() {
        // 队列的大小
        ArrayBlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3);

        System.out.println(blockingQueue.offer("a"));
        System.out.println(blockingQueue.offer("b"));
        System.out.println(blockingQueue.offer("c"));

        System.out.println(blockingQueue.peek());
        // System.out.println(blockingQueue.offer("d")); // false 不抛出异常！
        System.out.println("============================");
        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.poll()); // null  不抛出异常！
    }

    /**
     * 等待，阻塞（一直阻塞）
     */
    private static void test3() throws InterruptedException {
        // 队列的大小
        ArrayBlockingQueue<String > blockingQueue = new ArrayBlockingQueue<>(3);

        // 一直阻塞
        blockingQueue.put("a");
        blockingQueue.put("b");
        blockingQueue.put("c");
        // blockingQueue.put("d"); // 队列没有位置了，一直阻塞
        System.out.println(blockingQueue.take());
        System.out.println(blockingQueue.take());
        System.out.println(blockingQueue.take());
        System.out.println(blockingQueue.take()); // 没有这个元素，一直阻塞

    }


    /**
     * 等待，阻塞（等待超时）
     */
    private static void test4() throws InterruptedException {
        // 队列的大小
        ArrayBlockingQueue<String > blockingQueue = new ArrayBlockingQueue<>(3);

        blockingQueue.offer("a");
        blockingQueue.offer("b");
        blockingQueue.offer("c");
        // blockingQueue.offer("d",2,TimeUnit.SECONDS); // 等待超过2秒就退出
        System.out.println("===============");
        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.poll());
        blockingQueue.poll(2, TimeUnit.SECONDS); // 等待超过2秒就退出

    }


}
